<script setup lang="ts">
import { onMounted, ref } from "vue";
import * as THREE from "three";
import { OrbitControls } from "three/addons/controls/OrbitControls.js";

const container = ref<HTMLDivElement | null>(null);

onMounted(() => {
    init();
});

const init = () => {
    const { clientWidth, clientHeight } = container.value as HTMLDivElement;
    const scene = new THREE.Scene();
    const camera = new THREE.PerspectiveCamera(
        75,
        clientWidth / clientHeight,
        1,
        1000
    );
    camera.position.set(20, 20, 20);
    camera.lookAt(0, 0, 0);
    const renderer = new THREE.WebGLRenderer();
    renderer.setSize(clientWidth, clientHeight);
    container.value?.appendChild(renderer.domElement);

    const helper = new THREE.AxesHelper(10);
    scene.add(helper);

    const control = new OrbitControls(camera, renderer.domElement);

    initBox(scene);

    function render() {
        control.update();
        renderer.render(scene, camera);
        requestAnimationFrame(render);
    }
    render();
};

const initBox = (scene: THREE.Scene): THREE.Mesh => {
    // 顶点着色器
    const vertexShader = `
        // attribute vec3 position; // 默认 假设pos表示顶点位置坐标
        // uniform mat4 modelMatrix; // 默认 声明了一个变量mT，数据类型是mat4（4x4矩阵）
        // uniform mat4 viewMatrix; // 默认 视图矩阵
        // uniform mat4 projectionMatrix; // 投影矩阵
        void main() {
            // 投影矩阵 * 视图矩阵 * 模型矩阵 * 顶点坐标
            gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
            // gl_Position = projectionMatrix * viewMatrix * vec4(position, 1.0);
        }
    `;
    // 片源着色器
    const fragmentShader = `
        uniform vec3 color;
        uniform float opacity;
        void main() {
            gl_FragColor = vec4(color, opacity);
        }
    `;

    const geo = new THREE.PlaneGeometry(5, 5);

    console.log(geo.attributes);

    const material = new THREE.ShaderMaterial({
        uniforms: {
            color: {
                value: new THREE.Vector3(1, 0, 0),
            },
            opacity: {
                value: 1.0,
            },
        },
        vertexShader,
        fragmentShader,
        side: THREE.DoubleSide,
    });
    const mesh = new THREE.Mesh(geo, material);
    mesh.material.uniforms.opacity.value = 0.3;
    // mesh.position.x = 20;
    // mesh.rotateX(-(Math.PI / 2));
    scene.add(mesh);
    return mesh;
};
</script>

<template>
    <div ref="container" class="container"></div>
</template>

<style lang="less" scoped>
.container {
    width: 100%;
    height: 100%;
}
</style>
